/*
 * JGO2RDF creates a RDF representation of GAF2 files, which are automatically sourced from GO ftp site.
 * Copyright (C) 2012 Matthew M. Hindle & Artem Lysenko
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package uk.co.jgo2rdf.goa.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;
import java.util.Map.Entry;

public class DelimitedIO {

    public static List<String> readColumn(String file, int column, String delimiter) throws Exception {
        List<String> list = new ArrayList<String>();
        BufferedReader br = new BufferedReader(new FileReader(file));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            String[] data = strLine.split(delimiter);
            if (data.length > column) {
                list.add(data[column]);
            }
        }
        br.close();
        return list;
    }

    public static void saveToFile(Collection<?> data, String file, String delimiter) throws Exception {
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        for (Object object : data) {
            if (object instanceof Collection) {
                writeRow(bw, (Collection) object, delimiter);
            } else {
                bw.write(object.toString());
                bw.flush();
            }
            bw.write("\n");

        }
        bw.flush();
        bw.close();
    }

    private static void writeRow(BufferedWriter bw, Collection<?> row, String delimiter) throws Exception {
        if (row.size() == 0) {
            return;
        }
        Iterator<?> it = row.iterator();
        bw.write(it.next().toString());
        bw.flush();
        while (it.hasNext()) {
            bw.write(delimiter);
            Object o = it.next();
            if (o == null) {
                bw.write("");
            } else {
                bw.write(o.toString());
            }

            bw.flush();
        }
    }

    public static void saveToFile(Map<?, ?> data, String file, String delimiter) throws Exception {
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        for (Entry<?, ?> ent : data.entrySet()) {
            bw.write(ent.getKey().toString());
            bw.write(delimiter);
            Object object = ent.getValue();
            if (object instanceof Collection) {
                writeRow(bw, (Collection) object, delimiter);
            } else {
                bw.write(object.toString());
            }
            bw.write("\n");

        }
        bw.flush();
        bw.close();
    }

    public static void saveToFile(Collection<?> data, String file) throws Exception {
        saveToFile(data, file, "\t");
    }

    public static void saveToFile(Map<?, ?> data, String file) throws Exception {
        saveToFile(data, file, "\t");
    }

    public static Map<String, List<String>> readMap(String file, String delimiter) throws Exception {
        return readMap(file, delimiter, new HashMap<String, List<String>>());
    }

    public static Map<String, List<String>> readMap(String file, String delimiter, Map<String, List<String>> map) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(file));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            String[] data = strLine.split(delimiter);
            List<String> list = new ArrayList<String>();
            if (data.length > 1) {
                for (int i = 1; i < data.length; i++) {
                    list.add(i - 1, data[i]);
                }
            }
            map.put(data[0].trim(), list);
        }
        br.close();
        return map;
    }

    public static Map<String, String> readSimpleMap(String file, String delimiter) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        BufferedReader br = new BufferedReader(new FileReader(file));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            String[] data = strLine.split(delimiter);
            if (data.length > 1) {
                map.put(data[0].trim(), data[1].trim());
            }
        }
        br.close();
        return map;
    }


    public static List<List<String>> readList(String file, String delimiter) throws Exception {
        List<List<String>> list = new LinkedList<List<String>>();
        BufferedReader br = new BufferedReader(new FileReader(file));
        String strLine;
        while ((strLine = br.readLine()) != null) {
            list.add(Arrays.asList(strLine.split(delimiter)));
        }
        br.close();
        return list;
    }
}
